package service

import (
	"encoding/json"
	"qld2devservice/models"
	"qld2devservice/utils"
	"strconv"
	"strings"
	"time"

	dev "qld2devservice/proto"
)

const (
	OperateDeviceCloseIOValue  int32 = 0
	OperateDeviceOpenIOValue   int32 = 1
	OperateDeviceChangeIOValue int32 = 2
)

func MakeOperateDeviceCmdTopic(snNum string, devType int64, status int32) (sendTopic, recvTopic string) {
	if devType == 0 || devType == 1 || devType == 2 {
		return "server2device/" + snNum, "device2server/" + snNum
	} else if devType == 4 || devType == 5 {
		if status == OperateDeviceChangeIOValue && devType == 4 {
			return "SD/" + snNum + "/SA", "DS/" + snNum + "/SA"
		} else {
			return "SD/" + snNum + "/OC", "DS/" + snNum + "/OC"
		}
	} else if devType == 9 {
		return "SD/" + snNum + "/OC", "DS/" + snNum + "/OC"
	} else {
		return "", ""
	}
}
func MakeOperateDeviceCmdStr(snNum string, devType int64, status int32, operateType int64) (cmdStr string, err error) {
	if devType == 0 || devType == 1 || devType == 2 {
		data := make(map[string]interface{})
		data["DevPCode"] = snNum
		data["DevCode"] = "1"
		data["IOValue"] = status
		data["RealTime"] = time.Now().UnixNano() / 1e6
		dataJSON, err := json.Marshal(data)
		if err != nil {
			errNew := utils.WrapError(err, "MakeOperateDeviceCmd:控制语句生成失败")

			utils.MyPrint(utils.PRINT_ERROR, "MakeOperateDeviceCmd:1,", errNew)
			return "", errNew
		}
		return string(dataJSON), nil
	} else if devType == 4 {
		if status == OperateDeviceOpenIOValue {
			if operateType == 0 {
				return "1", nil
			} else if operateType == 1 {
				return "1Q", nil
			} else if operateType == 2 {
				return "1SQ", nil
			}
		} else if status == OperateDeviceCloseIOValue {
			return "0", nil
		} else if status == OperateDeviceChangeIOValue {
			if operateType == 0 {
				return "2", nil
			} else if operateType == 1 {
				return "3", nil
			} else if operateType == 2 {
				return "4", nil
			}
		}
	} else if devType == 5 {
		if status == OperateDeviceOpenIOValue {
			return "1", nil
		} else if status == OperateDeviceCloseIOValue {
			return "0", nil
		}
	} else if devType == 9 {
		if status == OperateDeviceOpenIOValue {
			return "1", nil
		} else if status == OperateDeviceCloseIOValue {
			return "0", nil
		}
	}
	return "", nil
}
func AnalyzeOperateDeviceCmdResponse(devType int64, status int32, cmdResponse string) (timeout bool, operateFlag int64, err error) {
	if devType == 0 || devType == 1 || devType == 2 { // 充电桩，小交流1.0，泛在充电桩
		var mapResult map[string]interface{}
		err = json.Unmarshal([]byte(cmdResponse), &mapResult)

		utils.MyPrint(utils.PRINT_WARN, cmdResponse)
		if err != nil {
			errNew := utils.NewError(utils.ErrorTypeStop, err.Error(), "AnalyzeOperateDeviceCmdResponse，MQTT设备控制,返回数据解析失败,返回:"+cmdResponse)
			utils.MyPrint(utils.PRINT_ERROR, "AnalyzeOperateDeviceCmdResponse:1,", errNew)
			return false, 1, nil
		} else {
			if mapResult["data"] != "ok" {
				errNew := utils.NewError(utils.ErrorTypeContinue, "AnalyzeOperateDeviceCmdResponse，MQTT设备控制,命令回应错误，返回:"+cmdResponse)
				utils.MyPrint(utils.PRINT_ERROR, "AnalyzeOperateDeviceCmdResponse:2,", errNew)
				return false, 1, nil
			} else {
				return false, 0, nil
			}
		}
	} else if devType == 4 { //小直流2.0
		utils.MyPrint(utils.PRINT_INFO, "AnalyzeOperateDeviceCmdResponse:3,", cmdResponse)
		if status == OperateDeviceOpenIOValue {
			if cmdResponse == "0" { //正常充电
				return false, 0, nil
			} else if cmdResponse == "1" { //电流异常
				return false, 2, nil
			} else if cmdResponse == "2" { //未检测到A电池电压
				return false, 3, nil
			} else if cmdResponse == "3" { //未检测到B电池电压
				return false, 4, nil
			} else if cmdResponse == "7" { //充电电流过小停止
				return false, 5, nil
			} else if cmdResponse == "8" { //充满电自主停止
				return false, 6, nil
			} else if cmdResponse == "i" { //电流挡位切换成功
				return false, 7, nil
			} else if cmdResponse == "v" { //电压挡位切换成功
				return false, 8, nil
			} else if cmdResponse == "e" { //正常结束充电
				return false, 9, nil
			} else if cmdResponse == "s" { //设备未回复电压电流功率
				return false, 10, nil
			} else if cmdResponse == "y" { //设备未回复错误状态
				return false, 11, nil
			} else if cmdResponse == "off-line" { //设备断开连接
				return false, 12, nil
			}
		} else if status == OperateDeviceChangeIOValue {
			if cmdResponse == "0" { //正常充电
				return false, 13, nil
			} else if cmdResponse == "1" { //电流异常
				return false, 2, nil
			} else if cmdResponse == "2" { //未检测到A电池电压
				return false, 3, nil
			} else if cmdResponse == "3" { //未检测到B电池电压
				return false, 4, nil
			} else if cmdResponse == "7" { //充电电流过小停止
				return false, 5, nil
			} else if cmdResponse == "8" { //充满电自主停止
				return false, 6, nil
			} else if cmdResponse == "i" { //电流挡位切换成功
				return false, 0, nil
			} else if cmdResponse == "v" { //电压挡位切换成功
				return false, 8, nil
			} else if cmdResponse == "e" { //正常结束充电
				return false, 9, nil
			} else if cmdResponse == "s" { //设备未回复电压电流功率
				return false, 10, nil
			} else if cmdResponse == "y" { //设备未回复错误状态
				return false, 11, nil
			} else if cmdResponse == "off-line" { //设备断开连接
				return false, 12, nil
			}
		} else if status == OperateDeviceCloseIOValue {
			if cmdResponse == "0" { //正常充电
				return false, 13, nil
			} else if cmdResponse == "1" { //电流异常
				return false, 2, nil
			} else if cmdResponse == "2" { //未检测到A电池电压
				return false, 3, nil
			} else if cmdResponse == "3" { //未检测到B电池电压
				return false, 4, nil
			} else if cmdResponse == "7" { //充电电流过小停止
				return false, 5, nil
			} else if cmdResponse == "8" { //充满电自主停止
				return false, 6, nil
			} else if cmdResponse == "i" { //电流挡位切换成功
				return false, 7, nil
			} else if cmdResponse == "v" { //电压挡位切换成功
				return false, 8, nil
			} else if cmdResponse == "e" { //正常结束充电
				return false, 0, nil
			} else if cmdResponse == "s" { //设备未回复电压电流功率
				return false, 10, nil
			} else if cmdResponse == "y" { //设备未回复错误状态
				return false, 11, nil
			} else if cmdResponse == "off-line" { //设备断开连接
				return false, 12, nil
			}
		}
		return false, 1, nil
	} else if devType == 5 { //小交流2.0
		utils.MyPrint(utils.PRINT_INFO, "开启后返回的信息:,", cmdResponse)
		if status == OperateDeviceOpenIOValue {
			//if cmdResponse == "0" { //正常充电
			//	return false, 0, nil
			//} else if cmdResponse == "9" { //漏电
			//	return false, 2, nil
			//} else if cmdResponse == "a" { //短路
			//	return false, 3, nil
			//} else if cmdResponse == "b" { //输出错误
			//	return false, 4, nil
			//} else if cmdResponse == "c" { //充满电自主停止
			//	return false, 5, nil
			//} else if cmdResponse == "d" { //充电时功率过小停止
			//	return false, 6, nil
			//} else if cmdResponse == "f" { //电压异常
			//	return false, 7, nil
			//} else if cmdResponse == "e" { //正常结束充电
			//	return false, 8, nil
			//} else if cmdResponse == "s" { //设备未回复电压电流功率
			//	return false, 9, nil
			//} else if cmdResponse == "y" { //设备未回复错误状态
			//	return false, 10, nil
			//} else if cmdResponse == "off-line" { //设备断开连接
			//	return false, 11, nil
			//}

			if cmdResponse == "0" { //正常充电
				return false, 0, nil
			} else if cmdResponse == "h" { //电流过大
				return false, 21, nil
			} else if cmdResponse == "2" || cmdResponse == "3" { //未连接电池
				return false, 22, nil
			} else if cmdResponse == "c" || cmdResponse == "8" { //充满停止
				return false, 8, nil
			} else if cmdResponse == "9" { //充电器及电池存在漏电风险
				return false, 24, nil
			} else if cmdResponse == "a" { //充电器及电池存在短路风险
				return false, 25, nil
			} else if cmdResponse == "b" { //充电器反馈异常
				return false, 26, nil
			} else if cmdResponse == "d" { //设备拔出停止
				return false, 27, nil
			} else if cmdResponse == "f" { //电网电压异常
				return false, 28, nil
			} else if cmdResponse == "7" { //充电电流过小停止
				return false, 29, nil
			} else if cmdResponse == "x" { //异常停止
				return false, 30, nil
			} else if cmdResponse == "off-line" || cmdResponse == "y" { //设备离线
				return false, 11, nil
			}
		} else if status == OperateDeviceCloseIOValue {
			if cmdResponse == "0" { //正常充电
				return false, 12, nil
			} else if cmdResponse == "9" { //漏电
				return false, 2, nil
			} else if cmdResponse == "a" { //短路
				return false, 3, nil
			} else if cmdResponse == "b" { //输出错误
				return false, 4, nil
			} else if cmdResponse == "c" { //充满电自主停止
				return false, 5, nil
			} else if cmdResponse == "d" { //充电时功率过小停止
				return false, 6, nil
			} else if cmdResponse == "f" { //电压异常
				return false, 7, nil
			} else if cmdResponse == "e" { //正常结束充电
				return false, 0, nil
			} else if cmdResponse == "s" { //设备未回复电压电流功率
				return false, 9, nil
			} else if cmdResponse == "y" { //设备未回复错误状态
				return false, 10, nil
			} else if cmdResponse == "off-line" { //设备断开连接
				return false, 11, nil
			}
		}
		return false, 0, nil
	} else if devType == 9 { //老年代步车
		utils.MyPrint(utils.PRINT_INFO, "AnalyzeOperateDeviceCmdResponse:3,", cmdResponse)
		if status == OperateDeviceOpenIOValue {
			if cmdResponse == "0" { //正常充电
				return false, 0, nil
			} else if cmdResponse == "9" { //漏电
				return false, 2, nil
			} else if cmdResponse == "a" { //短路
				return false, 3, nil
			} else if cmdResponse == "b" { //输出错误
				return false, 4, nil
			} else if cmdResponse == "c" { //充满电自主停止
				return false, 5, nil
			} else if cmdResponse == "d" { //充电时功率过小停止
				return false, 6, nil
			} else if cmdResponse == "f" { //电压异常
				return false, 7, nil
			} else if cmdResponse == "e" { //正常结束充电
				return false, 8, nil
			} else if cmdResponse == "s" { //设备未回复电压电流功率
				return false, 9, nil
			} else if cmdResponse == "y" { //设备未回复错误状态
				return false, 10, nil
			} else if cmdResponse == "off-line" { //设备断开连接
				return false, 11, nil
			}
		} else if status == OperateDeviceCloseIOValue {
			if cmdResponse == "0" { //正常充电
				return false, 12, nil
			} else if cmdResponse == "9" { //漏电
				return false, 2, nil
			} else if cmdResponse == "a" { //短路
				return false, 3, nil
			} else if cmdResponse == "b" { //输出错误
				return false, 4, nil
			} else if cmdResponse == "c" { //充满电自主停止
				return false, 5, nil
			} else if cmdResponse == "d" { //充电时功率过小停止
				return false, 6, nil
			} else if cmdResponse == "f" { //电压异常
				return false, 7, nil
			} else if cmdResponse == "e" { //正常结束充电
				return false, 0, nil
			} else if cmdResponse == "s" { //设备未回复电压电流功率
				return false, 9, nil
			} else if cmdResponse == "y" { //设备未回复错误状态
				return false, 10, nil
			} else if cmdResponse == "off-line" { //设备断开连接
				return false, 11, nil
			}
		}
		return false, 0, nil
	}
	return false, 1, nil
}

//	func makeMqttTopic(i int) (internalTopic []string) {
//		if devices[i].Type == 0 || devices[i].Type == 1 || devices[i].Type == 2 {
//			internalTopic = make([]string, 2)
//			internalTopic[0] = "device2server/" + devices[i].SnNum + "/1/totalstate"
//			internalTopic[1] = "device2server/" + devices[i].SnNum + "/1/power"
//		} else if devices[i].Type == 4 || devices[i].Type == 5 {
//			internalTopic = make([]string, 3)
//			internalTopic[0] = "DS/" + devices[i].SnNum + "/STS"
//			internalTopic[1] = "DS/" + devices[i].SnNum + "/err"
//			internalTopic[2] = "DS/" + devices[i].SnNum + "/CARD"
//		} else {
//			internalTopic = []string{""}
//		}
//		return
//	}
//
//	func MakeMqttListenDeviceTopic() (listenTopic []*dev.InternalTopic) {
//		deviceLength := len(devices)
//		topic := make([]*dev.InternalTopic, deviceLength)
//		for i := 0; i < deviceLength; i++ {
//			topic[i] = &dev.InternalTopic{InternalTopic: makeMqttTopic(i)}
//		}
//		return topic
//	}
//
//	func DevMqttMakeListenDeviceTopic() (listenTopic []*dev.DevMqttInternalTopic) {
//		deviceLength := len(devices)
//		topic := make([]*dev.DevMqttInternalTopic, deviceLength)
//		for i := 0; i < deviceLength; i++ {
//			topic[i] = &dev.DevMqttInternalTopic{InternalTopic: makeMqttTopic(i)}
//		}
//		return topic
//	}
func AnalyzeMqttListrnMessageResponse(topic, message string) (response string) {
	////临时添加——start
	//
	//if topic == "DS//err" || topic == "DS/q18012401000879/err" || topic == "DS/q18012401000878/err" || topic == "DS/q18012401000877/err" || topic == "DS/q18012401000876/err" || topic == "DS/q18012401000875/err" || topic == "DS/q18012401000874/err" || topic == "DS/q18012401000873/err" || topic == "DS/q18012401000872/err" || topic == "DS/q18012401000871/err" || topic == "DS/q18012401000870/err" {
	//	return ""
	//}
	////临时添加——end

	//临时添加——start

	if topic == "DS//err" || topic == "DS/q18012401000879/err" || topic == "DS/q18012401000878/err" || topic == "DS/q18012401000877/err" || topic == "DS/q18012401000876/err" || topic == "DS/q18012401000875/err" || topic == "DS/q18012401000874/err" || topic == "DS/q18012401000873/err" || topic == "DS/q18012401000872/err" || topic == "DS/q18012401000871/err" || topic == "DS/q18012401000870/err" {
		return ""
	}
	//临时添加——end

	utils.MyPrint(utils.PRINT_DEBUG, "AnalyzeMqttListrnMessageResponse", topic, "string:", message)

	result := strings.Split(topic, "/")
	if len(result) < 3 { //充电柜的只有两个，不支持
		return
	}
	response = "{\"data\":\"ok\"}"
	utils.MyPrint(utils.PRINT_WARN, topic, message)
	snNum := result[1]
	if len(snNum) == 0 {
		return
	}

	utils.MyPrint(utils.PRINT_DEBUG, "save snNum", snNum, "online")
	_, err := RedisSaveExpiration(snNum+"/online", "", 1800)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:7,控制语句生成失败"))
	}

	devType, err := getDevType(snNum)
	if err != nil {
		errNew := utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:设备类型获取失败")
		utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
		return
	}
	if devType == 0 {
		if len(result) != 4 {
			errNew := utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:topic格式错误")
			utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
			return
		}
		if result[2] != "1" {
			return
		}
		if result[3] == "totalstate" { //接收到totalstate
			AnalyzeStateMessage(snNum, message)
		} else if result[3] == "power" { //接收到power
			AnalyzePowerMessageType0(snNum, message)
		} else {
			utils.MyPrint(utils.PRINT_WARN, "topic格式未知")
			return
		}
	} else if devType == 1 {
		if len(result) != 4 {
			errNew := utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:topic格式错误")
			utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
			return
		}
		if result[3] == "totalstate" { //接收到totalstate
			AnalyzeStateMessage(snNum, message)
		} else if result[3] == "power" { //接收到power
			timetype, err1 := RedisGet(snNum+"/timeType", "0")
			if err1 != nil {
				AnalyzePowerMessageType1(snNum, message)
			}
			if timetype == "2" {
				AnalyzePowerMessageType1_1(snNum, message)
			} else {
				AnalyzePowerMessageType1(snNum, message)
			}

			//		AnalyzePowerMessageType1(snNum, message)
		} else {
			utils.MyPrint(utils.PRINT_WARN, "topic格式未知")
			return
		}
	} else if devType == 2 {
		if len(result) != 4 {
			errNew := utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:topic格式错误")
			utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
			return
		}
		if result[2] != "1" {
			return
		}
		if result[3] == "totalstate" { //接收到totalstate
			AnalyzeStateMessage(snNum, message)
		} else if result[3] == "power" { //接收到power
			AnalyzePowerMessageType2(snNum, message)
		} else {
			utils.MyPrint(utils.PRINT_WARN, "topic格式未知")
			return
		}
	} else if devType == 4 {
		if len(result) != 3 {
			errNew := utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:topic格式错误")
			utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
			return
		}
		if result[2] == "STS" { //接收到STS
			response = AnalyzePowerMessageType4(snNum, message)
		} else if result[2] == "err" { //接收到err,状态识别
			response, err = checkErrState(snNum, message)
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, err.Error())
			}
		} else if result[2] == "CARD" { //接收到刷卡
			AnalyzeCardMessageType4(snNum, message)
		} else {
			utils.MyPrint(utils.PRINT_WARN, "topic格式未知")
			return
		}
	} else if devType == 5 {
		if len(result) != 3 {
			errNew := utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:topic格式错误")
			utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
			return
		}
		if result[2] == "STS" { //接收到STS

			timetype, err1 := RedisGet(snNum+"/timeType", "0")
			if err1 != nil {
				response = AnalyzePowerMessageType5(snNum, message)
			}
			if timetype == "2" {
				response = AnalyzePowerMessageType5_1(snNum, message)
			} else {
				response = AnalyzePowerMessageType5(snNum, message)
			}

		} else if result[2] == "err" { //接收到err,状态识别
			response, err = checkErrState(snNum, message)
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, err.Error())
			}
		} else if result[2] == "CARD" { //接收到刷卡
			//fmt.Println("q1801230200019_3>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
			response = AnalyzeCardMessageType5(snNum, message)
		} else {
			utils.MyPrint(utils.PRINT_WARN, "topic格式未知")
			return
		}
	} else if devType == 9 {
		if len(result) != 3 {
			errNew := utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:topic格式错误")
			utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
			return
		}
		if result[2] == "STS" { //接收到STS
			timetype, err1 := RedisGet(snNum+"/timeType", "0")
			if err1 != nil {
				response = AnalyzePowerMessageType5(snNum, message)
			}
			if timetype == "2" {
				response = AnalyzePowerMessageType5_1(snNum, message)
			} else {
				response = AnalyzePowerMessageType5(snNum, message)
			}
		} else if result[2] == "err" { //接收到err,状态识别
			response, err = checkErrState(snNum, message)
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, err.Error())
			}
		} else if result[2] == "CARD" { //接收到刷卡
			response = AnalyzeCardMessageType5(snNum, message)
		} else {
			utils.MyPrint(utils.PRINT_WARN, "topic格式未知")
			return
		}
	}
	if statusStr, err := RedisGet(snNum+"/status", "2"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:1,设备是否在线etcd检查获取失败"))
	} else if statusStr != "1" { //是可用的
		if statusStr == "2" { // 已经离线，更新数据库，新上线
			if devType == -1 {
				// zhagnsen 20210816 modify
				strdev, err2 := RedisGet1("unsearchdev", "0")
				if err2 != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err2, "AnalyzeMqttListrnMessageResponse:unsearchdev获取失败"))
				}
				result := strings.Split(strdev, ",")
				for i := 0; i < len(result); i++ {
					if result[i] == snNum {
						return "数据库不存在该设备,无需再次查询"
					}
				}
				qldOutlets, err := models.GetQldOutletsBySnNum(snNum)
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
					return
				} else if len(qldOutlets) == 0 {
					// zhagnsen 20210816 modify
					strdev1, err4 := RedisGet("unsearchdev", "")
					if err4 != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err4, "AnalyzeMqttListrnMessageResponse:unsearchdev获取失败"))
					}
					if strdev1 == "" {
						strdev1 += snNum
					} else {
						strdev1 = strdev1 + "," + snNum
					}
					if err = RedisSave("unsearchdev", strdev1); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:3,unsearchdev保存失败"))
					}
					utils.MyPrint(utils.PRINT_WARN, snNum, "数据库不存在该设备")
					return "数据库不存在该设备"
				} else {
					devType = int64(qldOutlets[0].Type)
					devMap.Set(snNum, strconv.FormatInt(int64(qldOutlets[0].Type), 10))
				}
			}
			if devType > -1 {
				PutDevStatusChange(snNum, 0)
			}
			//if _, err = models.SetQldOutleStatus(snNum, 0); err != nil {
			//	utils.MyPrint(utils.PRINT_ERROR , utils.WrapError(err, "MakeOperateDeviceCmd:2,数据库设备上线信息更新失败"))
			//}
			if err = RedisSave(snNum+"/status", "0"); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:3,数据库etcd设备上线信息推送失败"))
			}
			if err = MqttNoticeSend(snNum+"/status", "0"); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:数据库etcd设备离线信息推送失败"))
			}
			if isWorking, err1 := RedisGet(snNum+"/isWorking", "0"); err1 != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "AnalyzeMqttListrnMessageResponse:1，etcd数据isWorking获取失败"))
			} else if isWorking == "1" {
				if err19 := RedisSave(snNum+"/powerPowerStartLowTime", time.Now().Format("2006-01-02 15:04:05")); err19 != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err19, "AnalyzeMqttListrnMessageResponse,1:etcd服务数据保存失败"))
				}
			}
		}

		time.AfterFunc(400*time.Second, func() {
			utils.MyPrint(utils.PRINT_WARN, "start check "+snNum+" online")
			if online, err := DevOnlineEtcdCheck(snNum); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:4,设备是否在线etcd检查获取失败"))
			} else if !online { // 已经离线，更新数据库，已离线
				if statusStr, err := RedisGet(snNum+"/status", "2"); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:1,设备是否在线etcd检查获取失败"))
				} else if statusStr == "0" { // 并且此时系统记录依旧是在线，更新
					if devType > -1 {
						PutDevStatusChange(snNum, 2)
					}
					//if _, err = models.SetQldOutleStatus(snNum, 2); err != nil {
					//	utils.MyPrint(utils.PRINT_ERROR , utils.WrapError(err, "MakeOperateDeviceCmd:5,数据库设备离线信息更新失败"))
					//}
					if err = RedisSave(snNum+"/status", "2"); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:6,数据库etcd设备离线信息推送失败"))
					}
					if err = MqttNoticeSend(snNum+"/status", "2"); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeMqttListrnMessageResponse:数据库etcd设备离线信息推送失败"))
					}
				}
			}
		})
	}

	return
}

func MakeEtcdListenKey(snNum string) (key []*dev.OutLetMakeEtcdListenKey) {
	qldOutlets, err := models.GetQldOutletsBySnNum(snNum)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, err.Error())
	} else if len(qldOutlets) == 0 {
		qldChargeBoxs, err := models.GetQldChargeBoxsByBoxSn(snNum)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, err.Error())
		} else if len(qldChargeBoxs) == 1 {
			qldChargeCabinets, err := models.GetQldChargeCabinetsBySnNum(qldChargeBoxs[0].CabinetSn)
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, err.Error())
			} else if len(qldChargeCabinets) == 1 {
				if qldChargeCabinets[0].Type == 3 {
					return []*dev.OutLetMakeEtcdListenKey{ //amount boxState orderFinish
						{SnNum: snNum, KeyName: "amount", KeyText: "/" + appName + "/" + snNum + "/amount", ValueType: "int"},
						{SnNum: snNum, KeyName: "electricity", KeyText: "/" + appName + "/" + snNum + "/electricity", ValueType: "float"},
						{SnNum: snNum, KeyName: "power", KeyText: "/" + appName + "/" + snNum + "/power", ValueType: "float"},
						{SnNum: snNum, KeyName: "voltage", KeyText: "/" + appName + "/" + snNum + "/voltage", ValueType: "float"},
						{SnNum: snNum, KeyName: "current", KeyText: "/" + appName + "/" + snNum + "/current", ValueType: "float"},
						{SnNum: snNum, KeyName: "boxState", KeyText: "/" + appName + "/" + snNum + "/boxState", ValueType: "int"},
						{SnNum: snNum, KeyName: "boxErrorChange", KeyText: "/" + appName + "/" + snNum + "/boxErrorChange", ValueType: "int"},
						{SnNum: snNum, KeyName: "orderFinish", KeyText: "/" + appName + "/" + snNum + "/orderFinish", ValueType: "json"},
					}
				}
			}
		} else if len(qldChargeBoxs) == 0 {
			qldChargeCabinets, err := models.GetQldChargeCabinetsBySnNum(snNum)
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, err.Error())
			} else if len(qldChargeCabinets) == 1 {
				if qldChargeCabinets[0].Type == 3 {
					return []*dev.OutLetMakeEtcdListenKey{ //amount boxState orderFinish
						{SnNum: snNum, KeyName: "cabinetStateChange", KeyText: "/" + appName + "/" + snNum + "/cabinetStateChange", ValueType: "int"},
					}
				}
			}
		}
	} else if len(qldOutlets) == 1 {
		if qldOutlets[0].Type == 4 || qldOutlets[0].Type == 6 {
			return []*dev.OutLetMakeEtcdListenKey{
				{SnNum: snNum, KeyName: "orderFinish", KeyText: "/" + appName + "/" + snNum + "/orderFinish", ValueType: "json"},
				{SnNum: snNum, KeyName: "status", KeyText: "/" + appName + "/" + snNum + "/status", ValueType: "int"},
				{SnNum: snNum, KeyName: "connectInfo", KeyText: "/" + appName + "/" + snNum + "/connectInfo", ValueType: "int"},
				{SnNum: snNum, KeyName: "state", KeyText: "/" + appName + "/" + snNum + "/state", ValueType: "string"},
				{SnNum: snNum, KeyName: "temp", KeyText: "/" + appName + "/" + snNum + "/temp", ValueType: "int"},
				{SnNum: snNum, KeyName: "electricity", KeyText: "/" + appName + "/" + snNum + "/electricity", ValueType: "float"},
				{SnNum: snNum, KeyName: "power", KeyText: "/" + appName + "/" + snNum + "/power", ValueType: "float"},
				{SnNum: snNum, KeyName: "voltage", KeyText: "/" + appName + "/" + snNum + "/voltage", ValueType: "float"},
				{SnNum: snNum, KeyName: "current", KeyText: "/" + appName + "/" + snNum + "/current", ValueType: "float"},
				{SnNum: snNum, KeyName: "amount", KeyText: "/" + appName + "/" + snNum + "/amount", ValueType: "int"},
				{SnNum: snNum, KeyName: "remainAmount", KeyText: "/" + appName + "/" + snNum + "/remainAmount", ValueType: "int"},
				{SnNum: snNum, KeyName: "soc", KeyText: "/" + appName + "/" + snNum + "/soc", ValueType: "float"},
				{SnNum: snNum, KeyName: "dSoc", KeyText: "/" + appName + "/" + snNum + "/dSoc", ValueType: "float"},
				{SnNum: snNum, KeyName: "timeLeft", KeyText: "/" + appName + "/" + snNum + "/timeLeft", ValueType: "int"},
			}
		}
	}
	return []*dev.OutLetMakeEtcdListenKey{
		{SnNum: snNum, KeyName: "orderFinish", KeyText: "/" + appName + "/" + snNum + "/orderFinish", ValueType: "json"},
		{SnNum: snNum, KeyName: "status", KeyText: "/" + appName + "/" + snNum + "/status", ValueType: "int"},
		{SnNum: snNum, KeyName: "connectInfo", KeyText: "/" + appName + "/" + snNum + "/connectInfo", ValueType: "string"},
		{SnNum: snNum, KeyName: "state", KeyText: "/" + appName + "/" + snNum + "/state", ValueType: "string"},
		{SnNum: snNum, KeyName: "temp", KeyText: "/" + appName + "/" + snNum + "/temp", ValueType: "int"},
		{SnNum: snNum, KeyName: "electricity", KeyText: "/" + appName + "/" + snNum + "/electricity", ValueType: "float"},
		{SnNum: snNum, KeyName: "power", KeyText: "/" + appName + "/" + snNum + "/power", ValueType: "float"},
		{SnNum: snNum, KeyName: "voltage", KeyText: "/" + appName + "/" + snNum + "/voltage", ValueType: "float"},
		{SnNum: snNum, KeyName: "current", KeyText: "/" + appName + "/" + snNum + "/current", ValueType: "float"},
		{SnNum: snNum, KeyName: "amount", KeyText: "/" + appName + "/" + snNum + "/amount", ValueType: "int"},
		{SnNum: snNum, KeyName: "remainAmount", KeyText: "/" + appName + "/" + snNum + "/remainAmount", ValueType: "int"},
	}
}

func MakeDevOnlineEtcdListenKey(snNum string) (key string, err error) {
	return "/" + appName + "/" + snNum + "/online", nil
}

func DevOnlineEtcdCheck(snNum string) (online bool, err error) {
	return RedisCheck(snNum + "/online")
}

func CheckOpenType(snNum string, openType int64) (result int64) {
	result = 1
	if devType, err := getDevType(snNum); err != nil {
		errNew := utils.WrapError(err, "CheckOpenType:获取设备类型失败")
		utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
		return
	} else if devType == 4 && (openType == 0 || openType == 1 || openType == 2) {
		result = 0
	}
	return
}

func GetOutletCurrentIn(snNum string) float32 {
	openType, err := GetOpenType(snNum)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, err.Error())
	}
	if openType == 0 {
		return 3
	} else if openType == 1 {
		return 4
	} else if openType == 2 {
		return 10
	}
	return 0
}
